/*
 *                  BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 * 
 * Created on Jun 28, 2007
 * 
 */

package org.biojava.services.das.servlets;


import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.SQLException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;


/** Provides a set of static utility functions to deal with
 * Images
 * 
 * @author Andreas Prlic
 *
 */
public class ImageUtil {

	

	/** Test if the image has transparent pixels
	 * 
	 * @param image
	 * @return true if is has transparency
	 */
    public static boolean hasAlpha(Image image) {
        // If buffered image, the color model is readily available
        if (image instanceof BufferedImage) {
            BufferedImage bimage = (BufferedImage)image;
            return bimage.getColorModel().hasAlpha();
        }
    
        // Use a pixel grabber to retrieve the image's color model;
        // grabbing a single pixel is usually sufficient
         PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
        try {
            pg.grabPixels();
        } catch (InterruptedException e) {
        }
    
        // Get the image's color model
        ColorModel cm = pg.getColorModel();
        return cm.hasAlpha();
    }
	
	/** convert an image to a BufferedImage
	 * 
	 * @param image
	 * @return a buffered image
	 */
	public static BufferedImage toBufferedImage(Image image) {
		
		//source: Java Developers Almanac
		
        if (image instanceof BufferedImage) {
        	//System.out.println("is a buffered image");
            return (BufferedImage)image;
        }
        
        
        System.out.println("not a buffered image, creating one...");
        
        // This code ensures that all the pixels in the image are loaded
        image = new ImageIcon(image).getImage();
    

        boolean hasAlpha = hasAlpha(image);
    
        // Create a buffered image with a format that's compatible with the screen
        BufferedImage bimage = null;
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        try {
            // Determine the type of transparency of the new buffered image
            int transparency = Transparency.OPAQUE;
            if (hasAlpha) {
                transparency = Transparency.BITMASK;
            }
    
            // Create the buffered image
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();
            bimage = gc.createCompatibleImage(
                image.getWidth(null), image.getHeight(null), transparency);
        } catch (HeadlessException e) {
        	System.out.println("in headless mode");
        	//e.printStackTrace();
            // The system does not have a screen
        }
    
        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            if (hasAlpha) {
                type = BufferedImage.TYPE_INT_ARGB;
            }
            bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
        }
    
        // Copy image to buffered image
        Graphics g = bimage.createGraphics();
    
        // Paint the image onto the buffered image
        g.drawImage(image, 0, 0, null);
        g.dispose();
    
        return bimage;
    }
	
	/** convert an Image to a ByteArray
	 * 
	 * @param image
	 * @param imageFormat the file format of the image to provide, e.g.  gif, jpg
	 * @return a byte array for the image
	 * @throws java.io.IOException
	 */
	public static byte[] toByteArray(Image image, String imageFormat) throws IOException {
		
		
		BufferedImage buffI = toBufferedImage(image);
		return toByteArray(buffI,imageFormat);
		

	}
	/** convert a BufferedImage to a ByteArray
	 * 
	 * @param buffI
	 * @param imageFormat the file format of the image to provide, e.g.  gif, jpg
	 * @return a byte array 
	 * @throws IOException
	 */
	public static byte[] toByteArray(BufferedImage buffI,String imageFormat) throws IOException{
		byte[] buffer = null;
		
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ImageIO.write(buffI, imageFormat, bos);

		buffer = bos.toByteArray();

		return buffer;
	}
	
	/** scales an image to a desired height
	 * 
	 * @param targetHeight
	 * @param image
	 * @return a scaled version of this image
	 */
	public static Image scaleImage(int targetHeight, Image image){
		int width = image.getWidth(null);
		int height = image.getHeight(null);

		//System.out.println("width " + width + " " + height);
		int thumbHeight = targetHeight;
		int div = height/thumbHeight;
		width = width/div;


		Image newImage = image.getScaledInstance(width, thumbHeight ,Image.SCALE_SMOOTH);
		//int nwidth = newImage.getWidth(null);
		//int nheight = newImage.getHeight(null);
		//System.out.println("width " + nwidth + " " + nheight);
		return newImage;
	}
	
	public static ImageIcon convertBlobToImageIcon(Blob image  ) throws IOException, SQLException{
		
		InputStream input = image.getBinaryStream();
		
		
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		// set read buffer size
		byte[] rb = new byte[1024];
		int ch = 0;
		// process blob
		while ((ch=input.read(rb)) != -1) {
			output.write(rb, 0, ch);
		}
		// transfer to byte buffer
		byte[] b = output.toByteArray();
		input.close();
		output.close();
		
		

		ImageIcon dPhoto = new ImageIcon(b);
		
		// set transparent background
		//Graphics2D g2D = (Graphics2D) dPhoto.getImage().getGraphics();
		
		//g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
		//Rectangle2D.Double rect = new Rectangle2D.Double(0,0,dPhoto.getIconWidth(),dPhoto.getIconHeight()); 
		//g2D.fill(rect);
		
		
		
		
		return dPhoto;
		
	}
	
}
